import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Optional;

public class IPUtils {

    public final static String IP_REGEX = "\\.";
    public final static String X_FORWARDED_FOR = "x-forwarded-for";
    public final static String X_FORWARDED_FOR_SPLIT = ",";
    public final static String UNKNOW = "unknown";
    public final static String X_REAL_IP = "X-Real-IP";
    public final static String PROXY_CLIENT_IP = "Proxy-Client-IP";
    public final static String WL_PROXY_CLIENT_IP = "WL-Proxy-Client-IP";
    public final static String IP_STRING = "%d.%d.%d.%d";

    /**
     * IP地址 字符型(String) 转 长整型(Long)
     *
     * @param ipAddress
     * @return
     */
    public static long INET_ATON(String ipAddress) {

        //ipAddress = "192.168.0." + RandomUtils.nextInt(0,200);

        // ipAddressInArray[0] = 192
        String[] ipAddressInArray = ipAddress.split(IP_REGEX);

        long result = 0;
        for (int i = 0; i < ipAddressInArray.length; i++) {

            int power = 3 - i;
            int ip = Integer.parseInt(ipAddressInArray[i]);

            // 1. 192 * 256^3
            // 2. 168 * 256^2
            // 3. 1 * 256^1
            // 4. 2 * 256^0
            result += ip * Math.pow(256, power);

        }

        return result;

    }

    /**
     * IP地址 长整型(Long) 转 字符型(String)
     *
     * @param ip
     * @return
     */
    public static String INET_NTOA(long ip) {
        return String.format(IP_STRING, (ip >> 24) & 0xFF, ((ip >> 16) & 0xFF), ((ip >> 8) & 0xFF), (ip & 0xFF));
    }

    /**
     * 获取客户端真实IP
     *
     * @param request
     * @return
     * @Author WR
     */
    public static String getIpAddressFromRequest(HttpServletRequest request) {
        String ip = request.getHeader(X_FORWARDED_FOR);
        if (StringUtils.isNotEmpty(ip) && !UNKNOW.equalsIgnoreCase(ip)) {
            String[] ips = ip.split(X_FORWARDED_FOR_SPLIT);
            ip = ips[0];
            if (StringUtils.isNotEmpty(ip) && !UNKNOW.equalsIgnoreCase(ip)) {
                return ip.trim();
            }
        }
        ip = request.getHeader(X_REAL_IP);
        if (StringUtils.isEmpty(ip) || UNKNOW.equalsIgnoreCase(ip)) {
            ip = request.getHeader(PROXY_CLIENT_IP);
        }
        if (StringUtils.isEmpty(ip) || UNKNOW.equalsIgnoreCase(ip)) {
            ip = request.getHeader(WL_PROXY_CLIENT_IP);
        }


        if (StringUtils.isEmpty(ip) || UNKNOW.equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return Optional.ofNullable(ip).orElse(StringUtils.EMPTY);
    }
}